home *** CD-ROM | disk | FTP | other *** search
/ Resource Library: Multimedia / Resource Library: Multimedia.iso / archvrs / msdos / xxdecode / xxdecode.c
Encoding:
C/C++ Source or Header  |  1993-02-11  |  6.8 KB  |  331 lines

  1.  
  2.  
  3. #ifndef lint
  4. static char sccsid[] = "@(#)xxdecode.c  5.3 (Berkeley) 4/10/85";
  5. #endif
  6.  
  7. /*
  8.  * xxdecode [input]
  9.  *
  10.  * create the specified file, decoding as you go.
  11.  * used with xxencode.
  12.  *
  13.  * note: with some MSDOS compilers a      #define MSDOS     is necessary.
  14.  */
  15.  
  16. #include <stdio.h>
  17. #include <ctype.h>
  18. #include <string.h>
  19. #ifndef MSDOS
  20. #ifndef VMCMS
  21. #include <pwd.h>
  22. #endif /* VMCMS */
  23. #else /* MSDOS */
  24. #include <fcntl.h>
  25. #include <io.h>
  26. #endif /* MSDOS */
  27.  
  28. #ifdef VMCMS
  29. #include <types.h>
  30. #include <stat.h>
  31. #include <dir.h>
  32. DIR * dir;
  33. #define perror(string) fprintf (stderr, "%s\n", string)
  34. #endif /* VMCMS */
  35.  
  36. /* single character decode */
  37. #define DEC(c)  ( table[ (c) & 0177 ] )
  38.  
  39. static char set[] = "+-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
  40. static char table[128];
  41. int replace;
  42.  
  43. main (argc, argv)
  44. int argc;
  45. char * argv [];
  46.  
  47. {
  48. FILE *in, *out;
  49. int mode;
  50. char source [128];
  51. char cdest [128];
  52. char * dest;
  53. char * temp;
  54. int i;
  55. char buf[80];
  56. int did = 0;
  57. int replflg = 0;
  58. int nameptr = 1;
  59.  
  60. if (argc > 1)
  61.     {
  62.     if (strcmp (argv [1], "-r") == 0 || strcmp (argv [1], "-R") == 0)
  63.         {
  64.         replflg = 1;
  65.         nameptr = 2;
  66.         }
  67.     }
  68. /* input filename */
  69. if (nameptr <= argc - 1)
  70.     {
  71.     strcpy (source, argv [nameptr]);
  72. #ifdef VMCMS
  73.     for (i = nameptr + 1; i < argc; i++)
  74.         {
  75.         strcat (source, " ");
  76.         strcat (source, argv [i]);
  77.         }
  78. #endif /* VMCMS */
  79.     if ((in = fopen(source, "r")) == NULL)
  80.         {
  81. #ifndef VMCMS
  82.         perror(source);
  83. #else /* VMCMS */
  84.         fprintf (stderr, "Cannot open file <%s>\n", source);
  85. #endif /* VMCMS */
  86.         exit(1);
  87.         }
  88.     }
  89. else
  90. #ifdef VMCMS
  91.     {
  92.     fprintf (stderr, "Usage: xxdecode [-r] fn ft [fm] ");
  93.     fprintf (stderr, "[> fn ft [fm] [(options] (bin]\n");
  94.     exit (2);
  95.     }
  96. #else
  97.     in = stdin;
  98. if (isatty (fileno (in)) || argc > 2)
  99.     {
  100.     fprintf (stderr, "Usage: xxdecode [-r] [infile]\n");
  101.     exit(2);
  102.     }
  103. #endif /* VMCMS */
  104.  
  105. while (1)
  106.     {
  107.     dest = cdest;
  108.     /* search for header line */
  109.     for (;;)
  110.         {
  111.         if (fgets(buf, sizeof buf, in) == NULL)
  112.             {
  113.             if (! did)
  114.                 {
  115.                 fprintf (stderr, "No begin line\n");
  116.                 exit (3);
  117.                 }
  118.             else
  119.                 exit (0);
  120.             }
  121.         if (strncmp(buf, "begin ", 6) == 0)
  122.             {
  123.             did = 1;
  124.             break;
  125.             }
  126.         }
  127.     sscanf(buf, "begin %o %s", &mode, dest);
  128.  
  129.     /* handle %user/file format */
  130.     if (dest[0] == '~')
  131.         {
  132. #ifndef VMCMS
  133. #ifndef MSDOS
  134.         char *sl;
  135.         struct passwd *getpwnam();
  136.         char *index();
  137.         struct passwd *user;
  138.         char dnbuf[100];
  139.  
  140.         sl = index(dest, '/');
  141.         if (sl == NULL)
  142.             {
  143.             fprintf(stderr, "Illegal ~user\n");
  144.             exit(3);
  145.             }
  146.         *sl++ = 0;
  147.         user = getpwnam(dest+1);
  148.         if (user == NULL)
  149.             {
  150.             fprintf(stderr, "No such user as %s\n", dest);
  151.             exit(4);
  152.             }
  153.         strcpy(dnbuf, user->pw_dir);
  154.         strcat(dnbuf, "/");
  155.         strcat(dnbuf, sl);
  156.         strcpy(dest, dnbuf);
  157. #else
  158.         dest++;
  159. #endif /* MSDOS */
  160. #endif /* VMCMS */
  161.         }
  162.     replace = replflg;
  163.     if (strcmp (dest, "/dev/stdout") != 0)
  164.         {
  165. #ifdef VMCMS
  166.         for (i = strlen (dest) - 1; i >= 0 && dest [i] != '/'; i--)
  167.             dest [i] = toupper (dest [i]);
  168.         dest = &dest [i + 1];
  169.         for (i = 0; dest [i] && dest [i] != '.'; i++)
  170.             dest [i] = toupper (dest [i]);
  171.         if (dest [i] == '.')
  172.             dest [i] = ' ';
  173.         for (; dest [i] && dest [i] != '.'; i++)
  174.             ;
  175.         if (dest [i] == '.')
  176.             dest [i] = '\0';
  177. #endif /* VMCMS */
  178.         };
  179.         replace = 1;
  180.     /* create output file */
  181.     if (replace)
  182.         {
  183.         fprintf (stderr, "Opening file: %s\n", dest);
  184.         if (strcmp (dest, "/dev/stdout") == 0)
  185.             out = stdout;
  186.         else
  187.             out = fopen(dest, "w");
  188. #ifdef MSDOS
  189.         if (setmode (fileno (out), O_BINARY) == -1)
  190.             {
  191.             perror ("Cannot open stdout as binary\n");
  192.             exit (3);
  193.             }
  194. #endif /* MSDOS */
  195.         if (out == NULL)
  196.             {
  197. #ifndef VMCMS
  198.             perror(dest);
  199. #else /* VMCMS */
  200.             fprintf (stderr, "Cannot open file <%s>\n", dest);
  201. #endif /* VMCMS */
  202.             exit(4);
  203.             }
  204. #ifndef VMCMS
  205.         chmod(dest, mode);
  206. #endif /* VMCMS */
  207.         }
  208.  
  209.     decode(in, out);
  210.  
  211.     if (fgets(buf,sizeof (buf), in) == NULL || strcmp (buf, "end\n"))
  212.         {
  213.         fprintf(stderr, "No end line\n");
  214.         exit(5);
  215.         }
  216.     }
  217. }
  218.  
  219. /*
  220.  * copy from in to out, decoding as you go along.
  221.  */
  222. decode(in, out)
  223. FILE *in;
  224. FILE *out;
  225. {
  226.         char buf[80];
  227.         char *bp;
  228.         int n;
  229.  
  230.         bp=table;       /* clear table */
  231.         for( n=128 ; n ; --n ) {
  232.           *(bp++) = 0;
  233.         };
  234.  
  235.         bp=set;         /* fill table */
  236.         for( n=64 ; n ; --n ) {
  237.           table[ *(bp++) & 0177 ] = 64-n;
  238.         };
  239.  
  240.         for (;;) {
  241.                 /* for each input line */
  242.                 if (fgets(buf, sizeof buf, in) == NULL) {
  243.                         printf("Short file\n");
  244.                         exit(10);
  245.                 }
  246.                 n = DEC(buf[0]);
  247.                 if (n <= 0)
  248.                         break;
  249.  
  250.                 bp = &buf[1];
  251.                 while (n > 0) {
  252.                         if (replace)
  253.                             outdec(bp, out, n);
  254.                         bp += 4;
  255.                         n -= 3;
  256.                 }
  257.         }
  258. }
  259.  
  260. /*
  261.  * output a group of 3 bytes (4 input characters).
  262.  * the input chars are pointed to by p, they are to
  263.  * be output to file f.  n is used to tell us not to
  264.  * output all of them at the end of the file.
  265.  */
  266. outdec(p, f, n)
  267. char *p;
  268. FILE *f;
  269. {
  270.         int c1, c2, c3;
  271.  
  272.         c1 = DEC(*p) << 2 | DEC(p[1]) >> 4;
  273.         c2 = DEC(p[1]) << 4 | DEC(p[2]) >> 2;
  274.         c3 = DEC(p[2]) << 6 | DEC(p[3]);
  275.         if (n >= 1)
  276.                 putc(c1, f);
  277.         if (n >= 2)
  278.                 putc(c2, f);
  279.         if (n >= 3)
  280.                 putc(c3, f);
  281. }
  282.  
  283.  
  284. /* fr: like read but stdio */
  285. int
  286. fr(fd, buf, cnt)
  287. FILE *fd;
  288. char *buf;
  289. int cnt;
  290. {
  291.         int c, i;
  292.  
  293.         for (i=0; i<cnt; i++) {
  294.                 c = getc(fd);
  295.                 if (c == EOF)
  296.                         return(i);
  297.                 buf[i] = c;
  298.         }
  299.         return (cnt);
  300. }
  301.  
  302. /*
  303.  * Return the ptr in sp at which the character c appears;
  304.  * NULL if not found
  305.  */
  306.  
  307. #define NULL    0
  308.  
  309. char *
  310. index(sp, c)
  311. register char *sp, c;
  312. {
  313.         do {
  314.                 if (*sp == c)
  315.                         return(sp);
  316.         } while (*sp++);
  317.         return(NULL);
  318. }
  319.  
  320.  
  321. /*
  322. **
  323. **
  324. **-- 
  325. **Fridrik Skulason   University of Iceland     |     Support Eastern Europe..
  326. **Technical Editor Virus Bulletin (UK).        |
  327. **E-Mail: frisk@rhi.hi.is   Fax: 354-1-28801   |     ..buy Prince Polo !
  328. **
  329. **
  330. */
  331.